package ormpool

import (
	"errors"
	"sync"
)

var TenantNoRegister = errors.New("tenant no register")
var HasUse = errors.New("the key is used")

type TenantId string

type TenantProxy interface {
	Bound(tid TenantId, key OrmKey) error
	DisBound(tid TenantId)
	GetDB(id TenantId) (DB, error)
	release(key OrmKey) error
}
type tenantProxy struct {
	ormProxy OrmProxy

	rwm          sync.RWMutex
	tidMapOrmKey map[TenantId]OrmKey
}

// NewTenantProxy 面向租户
func newTenantProxy(fac OrmProxy) TenantProxy {
	return &tenantProxy{ormProxy: fac, tidMapOrmKey: map[TenantId]OrmKey{}}
}

func (t *tenantProxy) Bound(tid TenantId, key OrmKey) error {
	t.rwm.Lock()
	defer t.rwm.Unlock()
	// 可以重复更新
	t.tidMapOrmKey[tid] = key
	return nil
}
func (t *tenantProxy) DisBound(tid TenantId) {
	t.rwm.Lock()
	defer t.rwm.Unlock()
	delete(t.tidMapOrmKey, tid)
}

func (t *tenantProxy) GetDB(id TenantId) (DB, error) {
	t.rwm.RLock()
	defer t.rwm.RUnlock()

	if t.ormProxy == nil {
		return nil, TenantNoRegister
	}
	ormKey, ok := t.tidMapOrmKey[id]
	if !ok {
		return nil, TenantNoRegister
	}
	db, exist := t.ormProxy.GetDB(ormKey)
	if !exist {
		return nil, TenantNoRegister
	}
	return db, nil
}
func (t *tenantProxy) release(key OrmKey) error {
	t.rwm.RLock()
	defer t.rwm.RUnlock()
	for _, ormKey := range t.tidMapOrmKey {
		if ormKey == key {
			return HasUse
		}
	}
	return t.ormProxy.Release(key)
}
